package com.fzy.core.action;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.fzy.core.BaseAction;
import com.fzy.core.BaseService;
import com.fzy.core.MyValidationAware;
import com.fzy.core.entity.MappingProperty;
import com.opensymphony.webwork.util.TokenHelper;
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.ModelDriven;
import com.opensymphony.xwork.Preparable;

public class SaveAction extends BaseAction implements ModelDriven,
		Preparable, MyValidationAware {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2513266197089818899L;
	Map entity;
	BaseService baseService;
	String errorDispatch;

	public void prepare() throws Exception {
		entity = new HashMap();
		errorDispatch = "dispatcher:/WEB-INF/jsp/input.jsp";
		
        Map session = ActionContext.getContext().getSession();
        synchronized (session) {
            if (!TokenHelper.validToken()) {
                addActionError(getText("error.duplicateSubmission"));
            }
        }
        if(!hasActionErrors()){
    		entity = validateId(request.getParameter("id"), getClassMapping());
    		if(hasActionErrors()){
    			errorDispatch = "redirect:list.do";
    		}
        }

	}

	public void validate() {
		for (Iterator iterator = getClassMapping().getProperties().iterator(); iterator.hasNext();) {
			MappingProperty property = (MappingProperty) iterator.next();
			Map params = getRequestParams();
			String name = property.getName();
			if("id".equals(name) || "status".equals(name) || "createdUser".equals(name) || "createdDate".equals(name) || "updatedUser".equals(name) || "updatedDate".equals(name))
				continue;
			Object value = params.get(name);
			if(!property.isNullAvailable() && !required(value)){
				String message = getText("error.required", new String[] { property.getShowName() });
				addFieldError(name, message);
			}
			if(MappingProperty.STRING == property.getType() && !maxLength((String)value, property.getLength())){
				String message = getText("error.maxLength", new String[] { property.getShowName(), property.getLength() + "" });
				addFieldError(name, message);
			}
		}
	}

	public String execute() throws Exception {
		baseService.saveEntityMapping(getClassMapping(), getRequestParams());

		addActionMessage(getText("success.save"));
		return "redirect:list.do";
	}

	public Map getEntity() {
		return entity;
	}

	public void setEntity(Map entity) {
		this.entity = entity;
	}

	public Object getModel() {
		return entity;
	}

	public void setBaseService(BaseService baseService) {
		this.baseService = baseService;
	}

	public String getErrorDispatch() {
		return errorDispatch;
	}
	
	private boolean required(Object value){
		boolean valid = true;
		if(value == null){
			valid = false;
		}else if(value instanceof String){
			String v = (String)value;
			if(StringUtils.isBlank(v))
				valid = false;
		}
		return valid;
	}
	private boolean maxLength(String value,int maxLength){
		if(value != null){
			int length = length(value);
			if(length > maxLength)
				return false;
		}
		return true;
	}
	
	private int length(String value) {
        int valueLength = 0;
        for (int i = 0; i < value.length(); i++) {
            String temp = value.substring(i, i + 1);
            if (isAssic(temp)) {
                valueLength += 1;
            } else {
                valueLength += 2;
            }
        }
        return valueLength;
    }
    
	private boolean isAssic(String src){
    	return src == null ? false : src.matches("[\u0000-\u00ff]+");
    }
}
